<template>
    <div class="container">
        <div class="left-container">
            <div style="display: flex; flex-direction: row;">
                <el-form class="info-form" :model="infoForm" label-width="auto" style=" flex: 1;max-width: 600px;">
                    <el-form-item label="贷款年限">
                        <el-input v-model="infoForm.duration" />
                    </el-form-item>
                    <el-form-item label="商业贷款（万）">
                        <el-input v-model="infoForm.commercialAmount" />
                    </el-form-item>
                    <el-form-item label="商业利率（%）">
                        <el-input v-model="infoForm.commercialRate" />
                    </el-form-item>
                    <el-form-item label="公积金贷款（万）">
                        <el-input v-model="infoForm.providentFundAmount" />
                    </el-form-item>
                    <el-form-item label="公积金利率（%）">
                        <el-input v-model="infoForm.providentFundRate" />
                    </el-form-item>
                    <el-form-item label="贷款方式">
                        <el-radio-group v-model="infoForm.type">
                            <el-radio :label="1">等额本息</el-radio>
                            <!-- <el-radio :label="2">等额本金</el-radio> -->
                        </el-radio-group>
                    </el-form-item>
                    <el-form-item>
                        <el-button type="primary" @click="compute">计算</el-button>
                    </el-form-item>
                </el-form>
                <div class="summary">
                    <p>
                        <span class="label">总贷款</span>
                        <span class="bold">{{ toTwo(summary.principal) }}</span>
                        <span class="label">元</span>
                    </p>
                    <p>
                        <span class="label">旧方案总还款</span>
                        <span class="bold">{{ toTwo(summary.oldSum) }}</span>
                        <span class="label">元</span>
                    </p>
                    <p>
                        <span class="label">共还款</span>
                        <span class="bold">{{ toTwo(summary.sum) }}</span>
                        <span class="label">元</span>
                    </p>
                    <p>
                        <span class="label">总计支付利息</span>
                        <span class="bold">{{ toTwo(summary.sum - summary.principal) }}</span>
                        <span class="label">元</span>
                    </p>
                    <p>
                        <span class="label">总计节省利息</span>
                        <span class="bold">{{ toTwo(summary.oldSum - summary.sum) }}</span>
                        <span class="label">元</span>
                    </p>
                    <p>
                        <span class="label">提前还款</span>
                        <span class="bold">{{ toTwo(summary.advanceCount) }}</span>
                        <span class="label">次</span>
                    </p>
                    <p>
                        <span class="label">共计提前还款</span>
                        <span class="bold">{{ toTwo(summary.advanceSum) }}</span>
                        <span class="label">元</span>
                    </p>
                    <p>
                        <span class="label">提前</span>
                        <span class="bold">{{ summary.advanceMonth }}</span>
                        <span class="label">还完贷款</span>
                    </p>
                </div>
            </div>

            <div class="advance-list">
                <p>提前还款（减少月供）</p>
                <el-button type="primary" @click="addAdvance()">添加</el-button>
                <el-button type="primary" @click="sort">排序</el-button>
                <el-button type="danger" @click="advance.list = []">清空</el-button>
                <div style=" display: inline-block;margin-bottom: 20px; margin-left: 40px;">
                    每
                    <el-input v-model="advance.date" style="width: 50px;" />
                    个周期提前还款
                    <el-input v-model="advance.money" style="width: 50px;" />
                    万元
                    <el-button type="primary" @click="batchAddAdvance">批量添加</el-button>
                </div>
                <div class="advance-item" v-for="(item, index) in advance.list" :key="item.id">
                    <span style="margin-right: 20px;">{{ index + 1 }}</span>
                    第
                    <el-input v-model="item.date" style="width: 50px;" />
                    期后提前还款
                    <el-input v-model="item.money" style="width: 50px;" />
                    万元
                    <el-button type="danger" @click="deleteAdvance(index)">删除</el-button>
                </div>
            </div>

        </div>
        <div class="right-container">
            <el-table :data="payList" stripe border :span-method="spanMethod" style="width: 550px;">
                <el-table-column prop="date" label="期数" width="70" />
                <el-table-column prop="pay" label="月供（元）" />
                <el-table-column prop="principal" label="本金（元）" />
                <el-table-column prop="interest" label="利息（元）" />
            </el-table>
        </div>
    </div>
</template>

<script lang="ts">
export default { name: '' }
</script>

<script lang="ts" setup>
import { reactive, ref, nextTick, onMounted, useAttrs, useSlots } from 'vue'

// const slots = useSlots()
// const attrs = useAttrs()
// const emits = defineEmits()

const infoForm = reactive({
    duration: 30,
    commercialAmount: 0,
    commercialRate: 3.25,
    providentFundAmount: 60,
    providentFundRate: 2.6,
    type: 1
})

const spanMethod = ({ row, column, rowIndex, columnIndex }) => {
    if (row.merge) {
        if (columnIndex === 0) {
            return [1, 4]
        } else {
            return [0, 0]
        }
    }
}

const advance = reactive({
    date: 12,
    money: 4,
    list: []
})

const addAdvance = (date = '', money = '') => {
    advance.list.push({
        id: new Date().getTime(),
        date: date,
        money: money
    })
}

const sort = () => {
    advance.list = advance.list.sort((a, b) => a.date - b.date)
}

const deleteAdvance = (index) => {
    advance.list.splice(index, 1)
}

const batchAddAdvance = () => {
    if (advance.date && advance.money && infoForm.duration) {
        advance.list = []
        for (let i = 1; i <= Math.floor(infoForm.duration * 12 / advance.date); i++) {
            addAdvance(advance.date * i, advance.money)
        }
    }
}

const payList = ref([])

const toTwo = (num) => {
    let result = Math.round(num * 100) / 100
    result = result.toFixed(2)
    return Number(result)
}

const summary = reactive({
    principal: 0,
    oldSum: 0,
    sum: 0,
    save: 0,
    advanceCount: 0,
    advanceSum: 0,
    advanceMonth: 0
})

// 等额本息计算：map，开始月份，剩余商业贷款本金，剩余公积金贷款本金
const debx = (startMonth, commercialAmount, providentFundAmount) => {
    const lastDuration = 12 * infoForm.duration - startMonth + 1
    let lastCommercialPrincipal = commercialAmount
    let lastProvidentFundPrincipal = providentFundAmount
    // 计算月还款金额：金额元，月利率，时间月
    const getDEBXmoney = (amount, rate, duration) => (amount * rate * Math.pow((1 + rate), duration)) / (Math.pow((1 + rate), duration) - 1)

    // 计算月还款本金：金额元，月利率，时间月，当前月数
    const getDEBXprincipal = (amount, rate, duration, current) => (amount * rate * Math.pow((1 + rate), current - 1)) / (Math.pow((1 + rate), duration) - 1)

    const commercialMoney = getDEBXmoney(commercialAmount, infoForm.commercialRate / 12 / 100, lastDuration)
    const providentFundMoney = getDEBXmoney(providentFundAmount, infoForm.providentFundRate / 12 / 100, lastDuration)
    const pay = toTwo(commercialMoney + providentFundMoney)
    if (startMonth === 1) {
        summary.oldSum = toTwo(pay * 12 * infoForm.duration)
    }
    for (let i = 1; i <= lastDuration; i++) {
        const commercialPrincipal = getDEBXprincipal(commercialAmount, infoForm.commercialRate / 12 / 100, lastDuration, i)
        const providentFundPrincipal = getDEBXprincipal(providentFundAmount, infoForm.providentFundRate / 12 / 100, lastDuration, i)
        payList.value.push({
            date: i + startMonth - 1,
            pay,
            principal: toTwo(commercialPrincipal + providentFundPrincipal),
            interest: toTwo(pay - commercialPrincipal - providentFundPrincipal)
        })
        lastCommercialPrincipal -= commercialPrincipal
        lastProvidentFundPrincipal -= providentFundPrincipal
        const index = advance.list.findIndex(item => Number(item.date) === i + startMonth - 1)
        const advanceItem = index !== -1 ? advance.list[index] : undefined
        if (advanceItem) {
            let sub = 0
            if (lastCommercialPrincipal > advanceItem.money * 10000) {
                lastCommercialPrincipal -= advanceItem.money * 10000
            } else {
                sub = advanceItem.money * 10000 - lastCommercialPrincipal
                lastCommercialPrincipal = 0
            }
            if (lastProvidentFundPrincipal > sub) {
                lastProvidentFundPrincipal -= sub
            } else {
                return payList.value.push({
                    date: `第${index + 1}次提前还款，本次提前还款${toTwo(lastProvidentFundPrincipal)}元，结清贷款`,
                    pay,
                    principal: 0,
                    interest: 0,
                    merge: true,
                    advance: true,
                    advanceMoney: toTwo(lastProvidentFundPrincipal)
                })
            }

            payList.value.push({
                date: `第${index + 1}次提前还款${advanceItem.money
                }万元，剩余商业贷款本金：${toTwo(lastCommercialPrincipal)
                }，剩余公积金贷款本金：${toTwo(lastProvidentFundPrincipal)
                }`,
                merge: true,
                advance: true,
                advanceMoney: advanceItem.money * 10000
            })

            return debx(i + startMonth, lastCommercialPrincipal, lastProvidentFundPrincipal)
        }
    }
}

const clearSummary = () => {
    summary.principal = 0
    summary.oldSum = 0
    summary.sum = 0
    summary.save = 0
    summary.advanceCount = 0
    summary.advanceSum = 0
    summary.advanceMonth = 0
}

const getSummary = () => {
    let allDate = 0
    payList.value.forEach(item => {
        if (item.advance) {
            summary.advanceCount++
            summary.advanceSum += Number(item.advanceMoney)
            summary.sum += Number(item.advanceMoney)
        } else {
            summary.sum += item.pay
            allDate++
        }
    })
    summary.principal = (infoForm.commercialAmount + infoForm.providentFundAmount) * 10000
    summary.advanceMonth = 12 * infoForm.duration - allDate
    if (summary.advanceMonth > 12) {
        const month = summary.advanceMonth % 12
        summary.advanceMonth = `${Math.floor(summary.advanceMonth / 12)}年${month ? month + '月' : ''}`
    }
}

const compute = () => {
    payList.value = []
    if (infoForm.type === 1) { // 等额本息
        clearSummary()
        debx(1, infoForm.commercialAmount * 10000, infoForm.providentFundAmount * 10000)
        getSummary()
    } else {
    }
}
</script>
<style lang="scss" scoped>
.container {
    display: flex;
    height: 100%;
    text-align: left;

    .left-container {
        display: flex;
        flex-direction: column;
        width: 650px;

        .advance-list {
            flex: 1;
            height: 0;
            overflow: auto;
            text-align: left;

            .advance-item {
                margin-bottom: 10px;
            }
        }

        .summary {
            width: 400px;
            text-align: left;

            p {
                .label {
                    display: inline-block;
                    width: 150px;
                }

                .label:first-child {
                    text-align: right;
                }

                .label:last-child {
                    text-align: left;
                }
            }

            .bold {
                display: inline-block;
                box-sizing: border-box;
                width: 100px;
                padding-left: 10px;
                font-weight: 600;
            }
        }
    }

    .right-container {
        height: 100%;
        overflow: auto;
    }
}
</style>